package leeon.bbsbrower.util;

import ipworks.Http;
import ipworks.HttpConnectedEvent;
import ipworks.HttpConnectionStatusEvent;
import ipworks.HttpDisconnectedEvent;
import ipworks.HttpEndTransferEvent;
import ipworks.HttpErrorEvent;
import ipworks.HttpEventListener;
import ipworks.HttpHeaderEvent;
import ipworks.HttpRedirectEvent;
import ipworks.HttpSetCookieEvent;
import ipworks.HttpStartTransferEvent;
import ipworks.HttpStatusEvent;
import ipworks.HttpTransferEvent;
import ipworks.IPWorksException;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.TooManyListenersException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ui.PlatformUI;

public class HTTPBean {

	private static HTTPBean httpBean = null;
	
	private Http http = null;
	
	private final ByteArrayOutputStream content = new ByteArrayOutputStream();
	
	private IProgressMonitor monitor;
	
	private String task;
		
	/**
	 * 私有的构造函数
	 * @param pxysrv
	 * @param pxypt
	 * @param pxyusr
	 * @param pxypw
	 * @throws IPWorksException
	 * @throws TooManyListenersException 
	 */
	private HTTPBean(String pxysrv, String pxypt, String pxyusr, String pxypw) throws IPWorksException {
		http = buildHttpBean(pxysrv, pxypt, pxyusr, pxypw);
	}
	
	private Http buildHttpBean(String pxysrv, String pxypt, String pxyusr, String pxypw) throws IPWorksException {
		Http http = new Http();
		http.setFollowRedirects(1);

		if (pxysrv != null && pxypt != null) {
			http.setProxyServer(pxysrv);
			http.setProxyPort(Integer.parseInt(pxypt));
			if (pxyusr != null && pxypw != null) {
				http.setProxyUser(pxyusr);
				http.setProxyPassword(pxypw);
			}
		}

		try {
			http.addHttpEventListener(new HttpEventListener() {
				public void connected(HttpConnectedEvent arg0) {}
				public void connectionStatus(HttpConnectionStatusEvent arg0) {}
				public void disconnected(HttpDisconnectedEvent arg0) {}
				public void endTransfer(HttpEndTransferEvent arg0) {
					if (monitor != null) {
						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
							public void run() {
								monitor.done();
							}
						});
						
					
					}
				}
				public void error(HttpErrorEvent arg0) {
					if (monitor != null) {
						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
							public void run() {
								monitor.done();
							}
						});
					}
				}
				public void header(HttpHeaderEvent arg0) {
					if ("Content-Length".equalsIgnoreCase(arg0.field)) {
						final int total = Integer.parseInt(arg0.value);
						if (monitor != null) {
							PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
								public void run() {
									monitor.beginTask(task, total);
								}
							});
						}
					}
				}
				public void redirect(HttpRedirectEvent arg0) {}
				public void setCookie(HttpSetCookieEvent arg0) {}
				public void startTransfer(HttpStartTransferEvent arg0) {}
				public void status(HttpStatusEvent arg0) {}

				
				public void transfer(final HttpTransferEvent arg0) {
					try {	
						content.write(arg0.text);
						if (monitor != null) {
							PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
								public void run() {
									monitor.worked((int)arg0.bytesTransferred);
								}
							});
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}				
			});
		} catch (TooManyListenersException e) {
			e.printStackTrace();
		}
		
		return http;
	}
	
	/**
	 * 获取http bean示例的方法
	 * @param pxysrv
	 * @param pxypt
	 * @param pxyusr
	 * @param pxypw
	 * @return
	 * @throws IPWorksException
	 * @throws TooManyListenersException 
	 */
	public static HTTPBean newInstance(String pxysrv, String pxypt, String pxyusr, String pxypw) throws IPWorksException {
		if (httpBean == null) {
			httpBean = new HTTPBean(pxysrv, pxypt, pxyusr, pxypw);
		}		
		return httpBean;
	}
	
	/**
	 * 获取http bean示例的方法
	 * @return
	 * @throws IPWorksException
	 * @throws TooManyListenersException 
	 */
	public static HTTPBean newInstance() throws IPWorksException {
		return newInstance(null, null, null, null);
	}
	
	
	/**
	 * 获取一个新的http实例
	 * @param pxysrv
	 * @param pxypt
	 * @param pxyusr
	 * @param pxypw
	 * @return
	 * @throws IPWorksException
	 */
	public static HTTPBean newAnotherInstance(String pxysrv, String pxypt, String pxyusr, String pxypw) throws IPWorksException {
		return new HTTPBean(pxysrv, pxypt, pxyusr, pxypw);
	}
	
	public static HTTPBean newAnotherInstance() throws IPWorksException {
		return newAnotherInstance(null, null, null, null);
	}
	
	/**
	 * 关闭连接和流
	 * @throws IOException
	 */
	public void close() throws IOException {
		http = null;
		content.close();
	}
	
	
	/**
	 * 使用get方法访问
	 * @param url
	 * @return
	 * @throws TooManyListenersException
	 * @throws IPWorksException
	 */
	public synchronized String get(String url) throws IPWorksException {
		if (http != null) {	
			content.reset();
			http.get(url);
			return content.toString();
		} else {
			return null;
		}
	}

	/**
	 * 使用get方法访问
	 * @param url
	 * @return
	 * @throws TooManyListenersException
	 * @throws IPWorksException
	 */
	public synchronized ByteArrayOutputStream getAsStream(String url) throws IPWorksException {
		this.task = url;
		if (http != null) {
			content.reset();
			http.get(url);
			return content;
		} else {
			return null;
		}
	}
	
	/**
	 * 通过map传递post的参数的方法
	 * @param url
	 * @param map
	 * @return
	 * @throws TooManyListenersException
	 * @throws IPWorksException
	 */
	public synchronized String post(String url, Map<String, String> map) throws IPWorksException {
		if (map != null) {
			Iterator<String> i = map.keySet().iterator();
			StringBuffer sb = new StringBuffer();
			while (i.hasNext()) {
				String key = i.next();
				String value = map.get(key);
				sb.append(key).append("=").append(value).append("&");
			}
			if (sb.length() != 0) {
				return post(url, sb.substring(0, sb.length()-1));
			} else {
				return post(url, "");
			}
		} else {
			return post(url, "");
		}
	}
	
	/**
	 * 使用post方法访问
	 * @param url
	 * @param data,格式就是a=1&b=2的格式
	 * @return
	 * @throws TooManyListenersException
	 * @throws IPWorksException
	 */
	public synchronized String post(String url, String data) throws IPWorksException {
		if (http != null) {			
			content.reset();			
			http.setContentType("application/x-www-form-urlencoded");			
			http.setPostData(data);
			http.post(url);
			return content.toString();
		} else {
			return null;
		}
	}	
	
	
	/**
	 * 添加通过map传入的cookie
	 * @param map
	 * @throws IPWorksException
	 */
	public synchronized void addCookie(Map<String, String> map) throws IPWorksException {
		if (map != null) {
			Iterator<String> i = map.keySet().iterator();
			while (i.hasNext()) {
				String key = i.next();
				String value = map.get(key);
				addCookie(key, value);
			}
		}
	}
	
	
	/**
	 * 添加通过key, value传入的cookie
	 * @param key
	 * @param value
	 * @throws IPWorksException
	 */
	public synchronized void addCookie(String key, String value) throws IPWorksException {
		if (http != null) {
			http.addCookie(key, value);
		}
	}
	
	public void setMonitor(IProgressMonitor monitor) {
		this.monitor = monitor;
	}
	
	/**
	 * @param args
	 * @throws IPWorksException 
	 * @throws TooManyListenersException 
	 */
	public static void main(String[] args) throws TooManyListenersException, IPWorksException {
	}

}
